package jsyntaxpane.util.intellisense.bsh;

import java.util.LinkedList;

/**
 * Parser para achar o escopo valido de um script ateh determinado ponto. Exclui strings e todo o conteudo entre { .. } ateh o ponto
 * passado. TODO ignorar comentarios
 * 
 * @author takeshi
 */
public class ScopeParser {

    private final CharSequence sequence;

    /**
     * @param sequence A {@link CharSequence}
     */
    public ScopeParser(CharSequence sequence) {
        super();
        this.sequence = sequence;
    }

    /**
     * Devolve o escopo valido ateh o ponto passado
     * 
     * @param limit int
     * @param preffix o prefixo a ser inserido
     * @return {@link String}
     */
    public String getValidScopeUpToExcludeString(int limit, String preffix) {
        boolean escape = false;
        boolean string = false;
        boolean character = false;
        final int max = Math.min(sequence.length(), limit);
        final LinkedList<StringBuilder> builders = new LinkedList<StringBuilder>();
        builders.add(new StringBuilder());
        for (int i = 0; i < max; i++) {
            char c = sequence.charAt(i);
            switch (c) {
            case '\"':
                if (escape) {
                    escape = false;
                } else {
                    string = !string;
                }
                break;
            case '\'':
                if (escape) {
                    escape = false;
                } else {
                    character = !character;
                }
                break;
            case '\\':
                builders.getLast().append(c);
                escape = true;
                break;
            case '{':
                if (!string && !character) {
                    builders.getLast().append(c);
                    builders.add(new StringBuilder());
                }
                break;
            case '}':
                if (!string && !character) {
                    builders.removeLast();
                    builders.getLast().append(c);
                }
                break;
            default:
                if (!string) {
                    builders.getLast().append(c);
                }
                break;
            }
        }
        StringBuilder res = new StringBuilder(preffix);
        for (StringBuilder stringBuilder : builders) {
            res.append(stringBuilder);
        }
        return res.toString();
    }

}
